import constant from './constant.js'
import repair_constant from './repair_constant.js'
import {
	Base64
} from 'js-base64';
import md5 from 'js-md5';
/**
 * 发起请求
 * @param {Object} url
 * @param {Object} param
 * @param {Object} callback
 */
function request(url, param, callback, complete, option) {
	option = optionInit(option);
	if (param && !param.timestamp) {
		param.timestamp = timestamp();
	}
	var paramWrapper = getParamWrapper(url, param, option)
	param.token = paramWrapper.token;
	param.sign = paramWrapper.sign;

	if (option.isNeedLog) {
		logObj("util.js >>> request() >>> data(真正传递到后端的参数)", param)
	}
	// url = "http://my.com:8080/login"
	uni.request({
		method: 'POST',
		url: url,
		data: param,
		//dataType: "",
		timeout: 30000,
		header: {
			'content-type': "application/x-www-form-urlencoded"
		},
		success: (res) => {
			if (option && option.isNeedShowLoading) {
				uni.hideLoading();
			}
			if (option.isNeedLog) {
				console.error("+ 响应：" + url)
				console.log(res);
			}
			if (option && option.isNeedToastError && res.data.code != 0 && res.data.code != 0) {
				toastError(res.data.msg, res.data.code)
			}
			if (res.data.code == 10004) {
				//10004 请重新登录 | 10025 用户未认证成功
				if (option.isNeedSignOut) {
					signOut(url);
				}
				if (option && !option.isInPageGuide) {
					//var route = getCurrentPages()[getCurrentPages().length - 1].route;
				}
			}
			callback(res)
		},
		fail: (res) => {
			if (option && option.isNeedToastError) {
				toastError(res.errMsg, -1)
			}
			if (option.isNeedLog) {
				console.error("+ 响应：" + url)
				console.log(res);
			}
		},
		complete: (res) => {
			if (complete) {
				complete()
			}
		}
	});
}

function upload(filePath, param, callback, option) {
	option = optionInit(option);
	if (param && !param.timestamp) {
		param.timestamp = timestamp();
	}
	let url = repair_constant.URLS.upload;
	var paramWrapper = getParamWrapper(url, param, option)
	param.token = paramWrapper.token;
	param.sign = paramWrapper.sign;
	
	if (option.isNeedLog) {
		logObj("util.js >>> request() >>> data(真正传递到后端的参数)", param)
	}
	uni.uploadFile({
		url: url, 
		filePath: filePath,
		name: 'file',
		formData: param,
		success: (uploadFileRes) => {
			console.log(uploadFileRes.data);
			callback(uploadFileRes.data)
		}
	});
}

function optionInit(option) {
	if (!option) {
		option = {
			isNeedToken: true,
			isNeedSignOut: true,
			isNeedShowLoading: false,
			isNeedToastError: true
		}
	}
	if (option.isNeedToken == undefined) {
		option.isNeedToken = true;
	}
	if (option.isNeedToastError == undefined) {
		option.isNeedToastError = true;
	}
	if (option.isNeedLog == undefined) {
		option.isNeedLog = true;
	}
	if (option && option.isNeedShowLoading) {
		showRequestLoading();
	}
	return option;
}

function showRequestLoading() {
	uni.showLoading({
		mask: true,
		title: '请稍候'
	})
}

function getParamWrapper(url, param, option) { //isNeedToken, isNeedSecretKey
	//判断是否登录
	const user = getUser();
	var isLogin_ = isLogin(user);
	var key = constant.SECRET_KEY; //'系统默认给出的secret_key';
	var token = '' //'登录后后台返回的token，没登录前为空字符串';
	if (isLogin_ && option && option.isNeedToken) {
		token = user.token; //
	}
	param.token = token;
	const keyCache = get(constant.KEY_SECRET);
	key = keyCache ? keyCache : key; //
	//参数按后台要求处理：
	var paramJson = JSON.stringify(param)
	var paramKeySortedArr = sort(param)
	var paramSortedCombineStr = combine(param, paramKeySortedArr)
	var paramSorted = sortedJsonObj(param, paramKeySortedArr)
	var paramSortedJson = JSON.stringify(paramSorted)
	var sign = md5(paramSortedCombineStr + key)
	var encrypt_data = Base64.encode(paramSortedJson, key);

	var paramWrapper = {
		token: token,
		param: encrypt_data,
		sign: sign,
	};

	if (option && option.isNeedLog) {
		console.error("+ 请求：" + url)
		console.log("+ paramSorted             = ")
		console.log(paramSorted)
		console.log("+ paramWrapperJson        = ")
		console.log(paramWrapper)
		console.log("+ isLogin                 = " + isLogin_)
		console.log("+ secret                  = " + key)
		console.log("+ secretKeyCache          = " + keyCache)
		console.log("+ token                   = " + token)

		if (true) {
			console.log("+                                                                    ")
			console.log("+ paramJson               = " + paramJson)
			console.log("+ paramKeySortedArr       = " + paramKeySortedArr)
			console.log("+ parmKeySortedCombineStr = " + paramSortedCombineStr)
			console.log("+ sign       			   = " + sign)
			console.log("+ paramSorted             = " + paramSorted)
			console.log("+ paramSortedJson         = " + paramSortedJson)
			console.log("+ encrypt_data            = " + encrypt_data)
		}
	}

	return paramWrapper;
}

function isLogin(user) {
	const user_ = user ? user : getUser();
	return user_.token ? true : false;
}

function signOut(url) {
	logMsg("清空用户数据 > url=" + (url ? url : ""))
	save(constant.KEY_USER, '{}')
	save(constant.KEY_SECRET, '')
	save(constant.KEY_SESSION_ID, '')
	save('encryptedData', '');
	save('iv', '');
	getApp().globalData.user = {};
}

function getUser() {
	try {
		var user = getApp().globalData.user.token ? getApp().globalData.user : JSON.parse(get(constant.KEY_USER));
		dealUserInfo(user);
		return user;
	} catch (e) {
		return {}
	}
}

/**
 * 数据转换处理，这里需要结合产品文档和业务逻辑
 * @param {Object} user
 */
function dealUserInfo(user, app) {
	//console.log(user);
}

/**
 * 1. 将 json 对象中的 key 提取出来、存入数组、按升序排序
 * @param {Object} jsonObj 原json对象
 */
function sort(jsonObj) {
	let arr = [];
	for (var key in jsonObj) {
		arr.push(key)
	}
	arr.sort();
	return arr;
}

/**
 * 将 jsonObj 中的 键值对，通过 key=value&key=value&... 的形式拼接起来
 * @param {Object} jsonObj 原json对象
 * @param {Object} keyArr  排序后的 key 的数组
 */
function combine(jsonObj, keyArr) {
	let str = '';
	for (var i in keyArr) {
		str += keyArr[i] + "=" + jsonObj[keyArr[i]] + "&"
	}
	//return str.substr(0, str.length - 1)
	return str; //(保留最后的&字符)
}

/**
 * @param {Object} jsonObj 原json对象
 * @param {Object} paramKeySortedArr
 */
function sortedJsonObj(jsonObj, paramKeySortedArr) {
	var result = {}
	for (var i in paramKeySortedArr) {
		//console.log("i = " + i)
		const key = paramKeySortedArr[i];
		//console.log("key = " + key)
		result[key] = jsonObj[key]
	}
	return result;
}

function timestamp() {
	return (new Date().getTime()).toString()
}

/**
 * 保存key value
 * 
 * @param {Object} key
 * @param {Object} value
 */
function saveSync(key, value) {
	try {
		uni.setStorageSync(key, value)
	} catch (e) {
		console.log("utils.js >>> save() >>> " + key + " = " + value + "保存失败！！！！！！！")
	}
}

function save(key, value) {
	uni.setStorage({
		key: key,
		data: value,
		success: function() {
			console.log(key + '数据缓存成功');
		}
	})
}

/**
 * 保存key value
 * 
 * @param {Object} key
 */
function get(key, def) {
	try {
		let get = uni.getStorageSync(key);
		return get == null || get == undefined || get.length == 0 ? (def ? def : "") : get;
	} catch (e) {
		console.log(e);
		console.log("utils.js >>> get() >>> " + key + "获取失败！！！！！！！")
		return def ? def : {};
	}
}

function showToast(title, duration, delay) {
	if (!title) {
		return;
	}
	var duration = duration ? duration : 2500;
	var delay = delay ? delay : 1000;
	setTimeout(function() {
		uni.showToast({
			title: title,
			icon: 'none',
			duration: duration
		})
	}, delay)
}

function toastError(msg, code) {
	if (code != 200) {
		console.error("util.js >>> toastError() >>> msg = " + msg + " code = " + code);
		var title = msg ? msg : "服务器开小差，请稍候再试" + (code ? "：" + code : '');
		setTimeout(function() {
			showToast(title);
		}, 200)
	}
}

function logMsg(where, msg) {
	console.log(where, msg);
}

function logObj(where, obj) {
	console.error(where + " ↓↓↓↓↓↓↓↓↓ ", obj ? obj : "")
}

function getSystemInfo(app) {
	uni.getSystemInfo({
		success(res) {
			console.log("getSystemInfo: ", res);

			let pxToRpxScale = 750 / res.windowWidth;
			let screenWidth = res.screenWidth * pxToRpxScale;
			let screenHeight = res.screenHeight * pxToRpxScale;

			app.globalData.pxToRpxScale = pxToRpxScale;

			app.globalData.screenWidth = screenWidth;
			app.globalData.screenHeight = screenHeight;

		}
	})
}

/**
 * @param {Object} str 字符串
 * @param {Object} max 最大显示字符
 */
function combine3(str, max) {
	if (!str) {
		return "";
	}
	return str.length > max ? (str.substr(0, max - 1) + "...") : str
}


function moneyFormat(value, isNeedSubLastDot, isNeedAddZero) { // 金额 格式化 
	if (value == '.') {
		return "";
	}
	var valueType = typeof value;
	var isNumber = valueType == 'number';
	var value_ = isNumber ? (value + '') : value; //如果value_是number类型，需要转换为string
	if (value_ != '' && value_.substr(0, 1) == '.') {
		value_ = 0
	}
	if (value_ == '') {
		value_ = 0
	}
	value_ = value_.replace(/^0*(0\.|[1-9])/, '$1') // 禁止粘贴
	value_ = value_.replace(/[^\d.]/g, '0.00') // 禁止输入非数字
	value_ = value_.replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的
	value_ = value_.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
	value_ = value_.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3') // 只能输入两个小数
	var isEndOfDot = value_[value_.length - 1] == '.';
	if (isEndOfDot && isNeedSubLastDot) {
		value_ = value_.substr(0, value_.length - 1)
	}
	if (value_.indexOf('.') < 0 && value_ != '') {
		// 以上已经过滤，此处控制的是如果没有小数点，首位不能为类似于 01、02的金额
		if (value_.substr(0, 1) == '0' && value_.length == 2) {
			value_ = value_.substr(1, value_.length)
		}
	}
	if (!value_) {
		value_ = 0
	}
	var isContainDotZero = value_.endsWith(".00")
	var dotIndex = value_.indexOf('.');
	var isHadDotNumber = dotIndex > 0 && dotIndex != (value_.length - 1); //是否已经有了小数位
	if (isNeedAddZero && !isContainDotZero && !isHadDotNumber) {
		var suffix = isEndOfDot ? "00" : ".00";
		value_ = value_ + suffix;
	} else if (isNeedAddZero && isHadDotNumber && dotIndex == (value_.length - 2)) { //11.1
		//如果已经有了小数位，并且只有一位小数末尾，在添加一个0
		value_ = value_ + "0";
	}
	return value_;
}

function calTotalPage(totalList) {
	if(totalList <= 10) {
		return 1;
	} 
	return totalList / 10 + (totalList % 10 > 0 ? 1 : 0)
}

export default {
	getSystemInfo,
	combine3,
	request,
	showRequestLoading,
	upload,
	getParamWrapper,
	isLogin,
	getUser,
	timestamp,
	save,
	saveSync,
	get,
	showToast,
	toastError,
	logMsg,
	logObj,
	signOut,
	moneyFormat,
	calTotalPage,
}